package userapp

import (
	"context"
	"fmt"
	grpcController "gitee.com/captials-team/ubdframe/src/apps/userapp/controllers/grpc"
	"gitee.com/captials-team/ubdframe/src/common"
	"gitee.com/captials-team/ubdframe/src/domain/configstc"
	etcdlib "gitee.com/captials-team/ubdframe/src/infrastructure/clients/etcd"
	v1log "gitee.com/captials-team/ubdframe/src/pkg/logs"
	"gitee.com/captials-team/ubdframe/src/pkg/uber_help"
	pbService "gitee.com/captials-team/ubdframe/src/protobufs/pb/service"
	"go.uber.org/dig"
	"google.golang.org/grpc"
	"net"
)

type RpcServer struct {
	di   *dig.Container
	conf *configstc.UserAppConfig

	server *grpc.Server
	module bool //是否作为模块服务
	l      v1log.ILog
}

func (s *RpcServer) RegisterService() error {
	return s.registerServices(s.server)
}

func (s *RpcServer) RegisterServiceForGRpc(server *grpc.Server) error {
	return s.registerServices(server)
}

func (s *RpcServer) registerServices(server *grpc.Server) error {

	common.ErrPanic(s.di.Invoke(func(authService pbService.UserServiceServer) {
		pbService.RegisterUserServiceServer(server, authService)
	}))

	return nil
}

func (s *RpcServer) WithModule(t bool) {
	s.module = t
}

func (s *RpcServer) Start() error {
	//作为模块不启动相关服务
	if s.module {
		return nil
	}

	//注册服务
	s.RegisterService()

	//使用注册服务-etcd
	etcdAddr := ""
	//etcdAddr = "127.0.0.1:2379" // 临时测试
	if len(etcdAddr) > 0 {
		srName := "setting_sr"

		sr := etcdlib.RegisterService(
			etcdAddr,
			srName,
			s.conf.RpcServer.Endpoint(), 5)
		go sr.ListenLease()
		defer sr.Close()
		s.l.Info("use discovery etcd %s", etcdAddr)
	}
	//启动服务
	lisAddr := s.conf.RpcServer.ListenAddr()
	//监听端口
	lis, err := net.Listen("tcp", lisAddr)
	common.ErrPanic(err)
	defer lis.Close()

	s.l.Info("RPC running at %s", lisAddr)
	defer s.l.Warn("RPC running complete")
	return s.server.Serve(lis)
}

func (s *RpcServer) Stop() error {
	s.server.Stop()
	defer s.l.Warn("RPC stop")
	return nil
}

func (s *RpcServer) interceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
	fmt.Println("token interceptor")
	fmt.Println("\t", req)
	fmt.Println("\t", info)

	return handler(ctx, req)
}

func NewRpcServer(di *dig.Container, conf *configstc.UserAppConfig, logger v1log.ILog) *RpcServer {
	s := &RpcServer{
		di:   di,
		conf: conf,
		l:    logger,
	}

	common.ErrPanic(di.Provide(grpcController.NewAuthServiceServer, dig.As(new(pbService.UserServiceServer))), uber_help.ErrAlreadyProvided)

	//启动
	server := grpc.NewServer(
		grpc.UnaryInterceptor(s.interceptor), //拦截器
	)

	s.server = server

	return s
}
